import random
import requests
import os
import json
import time
import random
import sqlite3
from typing import List, Dict, Optional, Any
from dataclasses import dataclass
from datetime import datetime
from urllib.parse import urljoin, urlparse

# 修复模块导入问题
import sys
import os
from src.processors.i2v_processor import transcode_video_for_recording

# 添加dashscope导入
import dashscope
from dashscope import Generation

# 添加项目根目录到Python路径
project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
if project_root not in sys.path:
    sys.path.append(project_root)

from tools.embed_ad import embed_football_ad_dir, embed_football_ad_single, embed_game_ad_dir, embed_game_ad_single
from tools.transcode import transcode_video_for_recording
from utils.video_database import VideoDatabase, VideoInfo
from processors.ghostcut_video_translator import GhostCutVideoTranslator
from processors.ghostcut_uploader import GhostCutUploader
from processors.platform_apis import get_endpoint_url, get_platform_config, get_endpoint_config, EndpointConfig



class TikHubDownloader:
    """多平台下载工具"""
    
    def __init__(self, api_key: Optional[str] = None, platform: str = "tikhub", base_url: str = None):
        """
        初始化下载器
        
        Args:
            api_key (str, optional): 平台API密钥
            platform (str): 平台名称，默认为"tikhub"
            base_url (str): API基础URL，如果未提供则使用默认配置
        """
        # 获取平台配置
        self.platform = platform
        self.platform_config = get_platform_config(platform)
        
        self.api_key = api_key or (os.environ.get(self.platform_config.api_key_env_var) if self.platform_config and self.platform_config.api_key_env_var else None)
        self.base_url = base_url or (self.platform_config.base_url if self.platform_config else "https://api.tikhub.io")
        self.db = VideoDatabase()
        self.session = requests.Session()
        
        # 如果提供了API密钥，设置请求头
        if self.api_key:
            headers = self.platform_config.default_headers.copy() if self.platform_config else {}
            headers["Authorization"] = f"Bearer {self.api_key}"
            headers["Content-Type"] = "application/json"
            self.session.headers.update(headers)
    
    def get_high_quality_video_url(self, aweme_id: Optional[str] = None, share_url: Optional[str] = None) -> Optional[Dict]:
        """
        获取视频的高质量播放链接
        
        Args:
            aweme_id (str, optional): 作品ID
            share_url (str, optional): 分享链接
            
        Returns:
            Dict: 包含视频ID和高质量播放链接的字典，失败时返回None
        """
        if not aweme_id and not share_url:
            print("必须提供aweme_id或share_url中的一个")
            return None
            
        try:
            # 获取平台端点配置
            endpoint_config = get_endpoint_config(self.platform, "fetch_video_high_quality_play_url")
            if not endpoint_config:
                # 根据平台设置默认端点
                if self.platform == "tiktok":
                    endpoint_config = EndpointConfig(
                        path="/api/v1/tiktok/app/v3/fetch_video_high_quality_play_url",
                        method="GET",
                        param_type="query"
                    )
                else:
                    endpoint_config = EndpointConfig(
                        path="/api/v1/douyin/app/v3/fetch_video_high_quality_play_url",
                        method="GET",
                        param_type="query"
                    )
            
            # 构建完整URL
            config = get_platform_config(self.platform)
            base_url = config.base_url if config else self.base_url
            url = f"{base_url}{endpoint_config.path}"
            
            # 根据平台设置参数
            params = {}
            if self.platform == "tiktok":
                if aweme_id:
                    params["aweme_id"] = aweme_id
                if share_url:
                    params["share_url"] = share_url
            else:  # 默认为douyin/tikhub
                if aweme_id:
                    params["aweme_id"] = aweme_id
                if share_url:
                    params["share_url"] = share_url
                
            print(f"请求高质量视频URL: {url}")
            print(f"请求参数: {params}")
            
            # 根据端点配置决定HTTP方法
            if endpoint_config.method.upper() == "POST":
                response = self.session.post(url, params=params if endpoint_config.param_type == "query" else None,
                                           json=params if endpoint_config.param_type == "json" else None)
            else:
                response = self.session.get(url, params=params)
            
            response.raise_for_status()
            
            data = response.json()
            print(f"API响应: {json.dumps(data, indent=2, ensure_ascii=False)[:500]}...")
            
            if data.get("code") == 200 and "data" in data:
                return data["data"]
            else:
                print(f"获取高质量视频URL失败: {data.get('message', '未知错误')}")
                return None
                
        except requests.exceptions.RequestException as e:
            print(f"网络请求错误: {e}")
            return None
        except Exception as e:
            print(f"获取高质量视频URL时出错: {e}")
            return None

    def collect_videos_by_keyword(self, keyword: str, count: int, platform: str = "douyin") -> List[Dict]:
        """
        根据关键字和数量收集视频
        
        Args:
            keyword (str): 搜索关键字
            count (int): 收集视频数量
            platform (str): 平台，默认为"douyin"
            
        Returns:
            List[Dict]: 收集到的视频列表
        """
        print(f"开始收集关键字 '{keyword}' 的视频，目标数量: {count}")
        
        collected_videos = []
        cursor = 0
        search_id = ""
        max_pages = count // 20 + 10
        
        # 根据平台设置默认参数
        if platform == "tiktok":
            # TikTok平台参数
            sort_type = "0"         # 综合排序
            publish_time = "0"      # 1天内
        else:
            # 默认抖音平台参数
            sort_type = "0"         # 综合排序
            publish_time = "0"      # 1天内
            filter_duration = "0-1"   # 0-1分钟的视频
            content_type = "1"      # 只搜索视频
        page = 0
        while len(collected_videos) < count and page < max_pages:
            if search_id == None:
                break;
            try:
                videos, search_id = self.search_videos_v3(
                    keyword=keyword,
                    platform=platform,
                    count=20,  # 每页最多20个或剩余需要的数量
                    cursor=20 * page,
                    sort_type=sort_type,
                    publish_time=publish_time,
                    filter_duration="0-1" if platform != "tiktok" else "0-1",  # TikTok不使用此参数
                    content_type="1" if platform != "tiktok" else "1",        # TikTok不使用此参数
                    search_id=search_id if platform != "tiktok" else ""       # TikTok不使用此参数
                )
                
                
                # 添加新获取的视频，同时过滤掉数据库中已存在的视频
                for video in videos:
                    # 根据平台获取aweme_id
                    if platform == "tiktok":
                        aweme_id = video.get('aweme_id')
                    else:
                        aweme_id = video.get('aweme_id')
                    
                    if not aweme_id:
                        continue
                    
                    # 检查是否已在当前收集的视频中
                    if any(v.get('aweme_id') == aweme_id for v in collected_videos):
                        continue
                    
                    # 检查数据库中是否已存在该视频
                    if not self.db.video_exists(aweme_id):
                        collected_videos.append(video)
                
                print(f"当前已收集 {len(collected_videos)} 个视频")
                
                # 如果已达到目标数量，结束搜索
                if len(collected_videos) >= count:
                    collected_videos = collected_videos[:count]
                    break
                
                # 更新游标用于下一页
                if platform == "tiktok":
                    # TikTok使用offset作为偏移量参数
                    cursor += min(20, count - len(collected_videos))
                else:
                    # 抖音使用cursor
                    cursor += len(videos)
                page=page+1
                # 添加延迟避免请求过于频繁
                time.sleep(1)
                
            except Exception as e:
                print(f"获取第 {page + 1} 页数据时出错: {e}")
                break
        
        print(f"视频收集完成，共收集到 {len(collected_videos)} 个视频")
        return collected_videos
    
    def search_videos_v3(self, keyword: str, platform: str = "douyin", count: int = 20, 
                        cursor: int = 0, sort_type: str = "0", publish_time: str = "0",
                        filter_duration: str = "0-1", content_type: str = "1", search_id: str = "") -> List[Dict[Any, Any]]:
        """
        使用V3接口根据关键词搜索视频
        
        Args:
            keyword (str): 搜索关键词
            platform (str): 平台 (douyin, tiktok, kuaishou等)
            count (int): 返回结果数量
            cursor (int): 游标，用于分页
            sort_type (str): 排序类型
            publish_time (str): 发布时间筛选
            filter_duration (str): 时长筛选
            content_type (str): 内容类型筛选
            search_id (str): 搜索ID，用于分页
            
        Returns:
            List[Dict]: 视频信息列表
        """
        max_retry = 10
        current = 0
        while(current <= max_retry):
        # 获取平台端点配置
            endpoint_config = get_endpoint_config(platform, "fetch_general_search_v3")
            if not endpoint_config:
                # 根据平台设置默认端点
                if platform == "tiktok":
                    endpoint_config = EndpointConfig(
                        path="/api/v1/tiktok/app/v3/fetch_video_search_result",
                        method="GET",
                        param_type="query"
                    )
                else:
                    endpoint_config = EndpointConfig(
                        path="/api/v1/douyin/search/fetch_video_search_v3",
                        method="POST",
                        param_type="json"
                    )
            
            # 构建完整URL
            config = get_platform_config(platform)
            base_url = config.base_url if config else self.base_url
            url = f"{base_url}{endpoint_config.path}"
            
            # 根据平台和端点配置设置请求参数
            if platform == "tiktok":
                # TikTok平台使用GET方法和查询参数
                params = {
                    "keyword": keyword,
                    "offset": cursor,
                    "count": 20,
                    "sort_type": sort_type,
                    "publish_time": publish_time
                }
                print(f"请求URL: {url}")
                print(f"请求参数: {params}")
                
                if endpoint_config.method.upper() == "GET":
                    response = self.session.get(url, params=params)
                else:
                    response = self.session.post(url, params=params)
            else:  # 默认为douyin/tikhub
                # 根据端点配置决定参数传递方式
                if endpoint_config.param_type == "json":
                    data = {
                        "keyword": keyword,
                        "offset": cursor,
                        "sort_type": sort_type,
                        "publish_time": publish_time,
                        "filter_duration": filter_duration,
                        "content_type": content_type,
                        "search_id": search_id
                    }
                    print(f"请求URL: {url}")
                    print(f"请求数据: {data}")
                else:  # query参数
                    data = {
                        "keyword": keyword,
                        "cursor": cursor,
                        "sort_type": sort_type,
                        "publish_time": publish_time,
                        "filter_duration": filter_duration,
                        "content_type": content_type,
                        "search_id": search_id
                    }
                    print(f"请求URL: {url}")
                    print(f"请求参数: {data}")
                
                # 根据端点配置决定HTTP方法
                if endpoint_config.method.upper() == "POST":
                    response = self.session.post(url, json=data if endpoint_config.param_type == "json" else None, 
                                            params=data if endpoint_config.param_type == "query" else None)
                else:
                    response = self.session.get(url, params=data)
            if response.status_code == 400:
                current += 1
                retry_interval = int(os.getenv("RETRY_INTERVAL", 10))
                print(f"第 {current} 次重试, {retry_interval}秒后重试")
                time.sleep(retry_interval)
                if current > max_retry:
                    print(f"尝试次数已超过最大限制，请检查接口是否正常")
                    return [], None
                continue
            result = response.json()
            videos, _search_id = self._parse_search_results_v3(result, platform, keyword)
            
            return videos, _search_id

    
    def _parse_search_results_v3(self, data: Dict, platform: str, keyword: str) -> List[Dict]:
        """
        解析V3搜索接口返回的数据
        
        Args:
            data (Dict): 搜索结果数据
            platform (str): 平台名称
            keyword (str): 搜索关键词
            count (int): 返回结果数量
            
        Returns:
            List[Dict]: 解析后的视频信息列表
        """
        videos = []
        try:
            if not isinstance(data, dict):
                print(f"数据格式错误，期望dict，实际{type(data)}")
                return videos
            
            # 打印数据的顶层键
            print(f"原始数据结构: {list(data.keys())}")
            print(f"cursor cursor : {data["data"]["cursor"]}")
            search_id = data["data"]["extra"]["logid"]
            # 检查必需的键
            if "data" not in data or not isinstance(data["data"], dict):
                print("数据中缺少 'data' 键或格式不正确")
                print(f"data键的类型: {type(data.get('data'))}")
                return videos
            
            data_section = data["data"]
            print(f"搜索数据类型: {type(data_section)}")
            
            if "data" not in data_section:
                print("数据中缺少 'data.data' 键")
                print(f"data键的内容: {list(data_section.keys())}")
                return videos
                
            if not isinstance(data_section["data"], list):
                print("数据中缺少 'data.data' 键或格式不正确")
                print(f"data.data键的类型: {type(data_section.get('data'))}")
                return videos
            
            video_list = data_section["data"]
            print(f"在 data['data'] 中找到 {len(video_list)} 个结果")
            
            # 如果有结果，打印第一个结果的结构
            if video_list and isinstance(video_list[0], dict):
                print(f"第一个结果的键: {list(video_list[0].keys())}")
            
            for item in video_list:
                if not isinstance(item, dict):
                    print(f"跳过非字典类型的项目: {type(item)}")
                    continue
                
                # 提取视频信息
                video_info = self._extract_video_info_v3(item, keyword)
                
                # 检查必要字段是否存在且非空
                if video_info and video_info["aweme_id"] and video_info["video_url"]:
                    videos.append(video_info)
                    # 打印前几个视频的信息
                    if len(videos) <= 3:
                        print(f"视频 {len(videos)}:")
                        print(f"  ID: {video_info['aweme_id']}")
                        print(f"  标题: {video_info['title'][:50]}...")
                        print(f"  作者: {video_info['author_name']}")
                        print(f"  播放量: {video_info['play_count']}")
                        print(f"  视频URL: {video_info['video_url'][:50]}...")
                else:
                    if video_info:
                        missing_fields = []
                        if not video_info.get("aweme_id"):
                            missing_fields.append("aweme_id")
                        if not video_info.get("video_url"):
                            missing_fields.append("video_url")
                        print(f"跳过不完整的视频数据，缺少字段: {missing_fields}")
            
            print(f"解析后的视频列表数量: {len(videos)}")
            
        except Exception as e:
            print(f"解析搜索结果时出错: {e}")
            import traceback
            traceback.print_exc()
            # 打印部分数据内容用于调试
            if isinstance(data, dict):
                print(f"数据内容 (前200字符): {str(data)[:200]}")
            elif isinstance(data, list) and len(data) > 0:
                print(f"数据内容 (第一个元素前200字符): {str(data[0])[:200]}")
        
        return videos, search_id
    
    def _extract_video_info_v3(self, aweme_info: Dict, keyword: str) -> Optional[Dict]:
        """
        从V3接口的aweme_info中提取视频信息
        
        Args:
            aweme_info (Dict): 视频详细信息
            keyword (str): 搜索关键词
            
        Returns:
            Dict: 提取的视频信息
        """
        try:
            if not isinstance(aweme_info, dict):
                return None
            
            # 检查aweme_info是否嵌套在aweme_info字段中
            if "aweme_info" in aweme_info and isinstance(aweme_info["aweme_info"], dict):
                aweme_data = aweme_info["aweme_info"]
            else:
                aweme_data = aweme_info
            
            aweme_id = aweme_data.get("aweme_id", "")
            
            video_info = {
                "aweme_id": aweme_id,
                "platform": "douyin",
                "title": aweme_data.get("desc", ""),
                "description": aweme_data.get("desc", ""),
                "duration": aweme_data.get("duration", 0),
                "cover_url": "",
                "video_url": "",
                "author_name": "",
                "author_id": "",
                "play_count": 0,
                "like_count": 0,
                "comment_count": 0,
                "search_keyword": keyword
            }
            
            # 检查aweme_id是否为空
            if not aweme_id:
                print("无法提取aweme_id")
                return None
            
            # 提取封面URL
            if "video" in aweme_data:
                video = aweme_data["video"]
                # 尝试多种封面URL
                cover_keys = ["cover", "origin_cover", "dynamic_cover"]
                for cover_key in cover_keys:
                    if cover_key in video and "url_list" in video[cover_key] and isinstance(video[cover_key]["url_list"], list) and video[cover_key]["url_list"]:
                        video_info["cover_url"] = video[cover_key]["url_list"][0]
                        break
            

            if "video" in aweme_data and "play_addr" in aweme_data["video"]:
                play_addr = aweme_data["video"]["play_addr"]
                if "url_list" in play_addr and isinstance(play_addr["url_list"], list) and play_addr["url_list"]:
                    url_list = play_addr["url_list"]
                    filtered_urls = [url for url in url_list if "mime_type=video_mp4" in url]
                    if len(filtered_urls) > 0:
                        video_info["video_url"] = filtered_urls[0]
            
            # 提取作者信息
            if "author" in aweme_data:
                author = aweme_data["author"]
                video_info["author_name"] = author.get("nickname", "")
                video_info["author_id"] = author.get("uid", author.get("sec_uid", ""))
            
            # 提取统计数据
            if "statistics" in aweme_data:
                stats = aweme_data["statistics"]
                video_info["play_count"] = stats.get("play_count", 0)
                video_info["like_count"] = stats.get("digg_count", 0)
                video_info["comment_count"] = stats.get("comment_count", 0)
            
            return video_info
        except Exception as e:
            print(f"提取视频信息时出错: {e}")
            return None
    
    def search_videos(self, keyword: str, platform: str = "douyin", count: int = 20) -> List[Dict[Any, Any]]:
        """
        根据关键词搜索视频
        
        Args:
            keyword (str): 搜索关键词
            platform (str): 平台 (douyin, tiktok, kuaishou等)
            count (int): 返回结果数量
            
        Returns:
            List[Dict]: 视频信息列表
        """
        try:
            # 根据平台选择不同的搜索API端点
            if platform.lower() == "douyin":
                # 使用正确的抖音搜索端点
                endpoint = "/api/v1/douyin/app/v3/fetch_general_search_result"
                params = {
                    "keyword": keyword,
                    "count": count
                }
            elif platform.lower() == "tiktok":
                # 使用正确的TikTok搜索端点
                endpoint = "/api/v1/tiktok/web/search_video"
                params = {
                    "keywords": keyword,
                    "count": count
                }
            else:
                # 默认使用抖音搜索
                endpoint = "/api/v1/douyin/app/v3/fetch_general_search_result"
                params = {
                    "keyword": keyword,
                    "count": count
                }
            
            url = f"{self.base_url}{endpoint}"
            print(f"请求URL: {url}")
            print(f"请求参数: {params}")
            
            response = self.session.get(url, params=params)
            response.raise_for_status()
            
            data = response.json()
            print(f"API响应数据: {json.dumps(data, indent=2, ensure_ascii=False)[:500]}...")
            
            videos = self._parse_search_results(data, platform, keyword)
            print(f"解析后的视频列表数量: {len(videos)}")
            
            # 打印解析后的视频信息
            for i, video in enumerate(videos[:3]):  # 只打印前3个
                print(f"视频 {i+1}:")
                print(f"  ID: {video.get('video_id')}")
                print(f"  标题: {video.get('title')}")
                print(f"  作者: {video.get('author_name')}")
                print(f"  播放量: {video.get('play_count')}")
                print(f"  视频URL: {video.get('video_url')[:50] if video.get('video_url') else 'N/A'}...")
            
            return videos
            
        except requests.exceptions.RequestException as e:
            print(f"网络请求错误: {e}")
            return []
        except Exception as e:
            print(f"搜索视频时出错: {e}")
            return []
    
    def _parse_search_results(self, data: Dict, platform: str, keyword: str) -> List[Dict]:
        """
        解析搜索结果
        
        Args:
            data (Dict): API返回的原始数据
            platform (str): 平台名称
            keyword (str): 搜索关键词
            
        Returns:
            List[Dict]: 解析后的视频信息列表
        """
        videos = []
        
        try:
            print(f"原始数据结构: {list(data.keys()) if isinstance(data, dict) else type(data)}")
            
            # 根据不同平台解析数据
            if platform == "douyin":
                # 抖音搜索结果解析 - data字段是包含复杂结构的列表
                if isinstance(data, dict) and "data" in data and isinstance(data["data"], list):
                    print(f"在 data 中找到 {len(data['data'])} 个元素")
                    for item in data["data"]:
                        # 检查item中的data字段，这可能包含实际的视频列表
                        if isinstance(item, dict) and "data" in item and isinstance(item["data"], list):
                            print(f"在 item['data'] 中找到 {len(item['data'])} 个视频")
                            for video_item in item["data"]:
                                video_info = self._extract_douyin_video_info(video_item, keyword)
                                if video_info and video_info["video_id"]:
                                    videos.append(video_info)
                        # 或者检查item中的aweme_list字段
                        elif isinstance(item, dict) and "aweme_list" in item and isinstance(item["aweme_list"], list):
                            print(f"在 item['aweme_list'] 中找到 {len(item['aweme_list'])} 个视频")
                            for video_item in item["aweme_list"]:
                                video_info = self._extract_douyin_video_info(video_item, keyword)
                                if video_info and video_info["video_id"]:
                                    videos.append(video_info)
            elif platform == "tiktok":
                # TikTok搜索结果解析
                if isinstance(data, dict) and "item_list" in data:
                    for item in data["item_list"]:
                        video_info = self._extract_tiktok_video_info(item, keyword)
                        if video_info and video_info["video_id"]:
                            videos.append(video_info)
            else:
                # 通用解析
                if isinstance(data, list):
                    videos = data[:20]  # 限制数量
                elif isinstance(data, dict):
                    # 尝试常见的数据结构
                    if "videos" in data and isinstance(data["videos"], list):
                        videos = data["videos"][:20]
                    elif "data" in data and isinstance(data["data"], list):
                        # 检查data中的每个元素
                        for item in data["data"]:
                            if isinstance(item, dict):
                                # 如果item中有aweme_list
                                if "aweme_list" in item and isinstance(item["aweme_list"], list):
                                    for video_item in item["aweme_list"]:
                                        video_info = self._extract_douyin_video_info(video_item, keyword)
                                        if video_info and video_info["video_id"]:
                                            videos.append(video_info)
                                # 如果item中有data
                                elif "data" in item and isinstance(item["data"], list):
                                    for video_item in item["data"]:
                                        video_info = self._extract_douyin_video_info(video_item, keyword)
                                        if video_info and video_info["video_id"]:
                                            videos.append(video_info)
                                # 如果item本身就是视频对象
                                else:
                                    video_info = self._extract_douyin_video_info(item, keyword)
                                    if video_info and video_info["video_id"]:
                                        videos.append(video_info)
                    elif isinstance(data["data"], list):
                        videos = data["data"][:20]
        except Exception as e:
            print(f"解析搜索结果时出错: {e}")
            # 打印部分数据内容用于调试
            if isinstance(data, dict):
                print(f"数据内容 (前200字符): {str(data)[:200]}")
            elif isinstance(data, list) and len(data) > 0:
                print(f"数据内容 (第一个元素前200字符): {str(data[0])[:200]}")
        
        return videos
    
    def _extract_douyin_video_info(self, item: Dict, keyword: str) -> Optional[Dict]:
        """提取抖音视频信息"""
        try:
            if not isinstance(item, dict):
                return None
                
            video_info = {
                "video_id": item.get("aweme_id", ""),
                "platform": "douyin",
                "title": item.get("desc", ""),
                "description": item.get("desc", ""),
                "duration": item.get("duration", 0),
                "cover_url": "",
                "video_url": "",
                "author_name": "",
                "author_id": "",
                "play_count": 0,
                "like_count": 0,
                "comment_count": 0,
                "search_keyword": keyword
            }
            
            # 提取封面URL
            if "video" in item and "cover" in item["video"]:
                cover = item["video"]["cover"]
                if "url_list" in cover and isinstance(cover["url_list"], list) and cover["url_list"]:
                    video_info["cover_url"] = cover["url_list"][0]
            
            # 提取视频URL
            if "video" in item and "play_addr" in item["video"]:
                play_addr = item["video"]["play_addr"]
                if "url_list" in play_addr and isinstance(play_addr["url_list"], list) and play_addr["url_list"]:
                    video_info["video_url"] = play_addr["url_list"][0]
            
            # 提取作者信息
            if "author" in item:
                author = item["author"]
                video_info["author_name"] = author.get("nickname", "")
                video_info["author_id"] = author.get("uid", author.get("sec_uid", ""))
            
            # 提取统计数据
            if "statistics" in item:
                stats = item["statistics"]
                video_info["play_count"] = stats.get("play_count", 0)
                video_info["like_count"] = stats.get("digg_count", 0)
                video_info["comment_count"] = stats.get("comment_count", 0)
            
            return video_info
        except Exception as e:
            print(f"提取抖音视频信息时出错: {e}")
            return None
    
    def _extract_tiktok_video_info(self, item: Dict, keyword: str) -> Optional[Dict]:
        """提取TikTok视频信息"""
        try:
            if not isinstance(item, dict):
                return None
                
            video_info = {
                "video_id": item.get("id", ""),
                "platform": "tiktok",
                "title": item.get("desc", ""),
                "description": item.get("desc", ""),
                "duration": item.get("video", {}).get("duration", 0),
                "cover_url": "",
                "video_url": "",
                "author_name": "",
                "author_id": "",
                "play_count": 0,
                "like_count": 0,
                "comment_count": 0,
                "search_keyword": keyword
            }
            
            # 提取封面URL
            if "video" in item and "cover" in item["video"]:
                video_info["cover_url"] = item["video"]["cover"].get("display_url", "")
            
            # 提取视频URL
            if "video" in item and "play_addr" in item["video"]:
                video_info["video_url"] = item["video"]["play_addr"]
            
            # 提取作者信息
            if "author" in item:
                author = item["author"]
                video_info["author_name"] = author.get("unique_id", author.get("nickname", ""))
                video_info["author_id"] = author.get("id", "")
            
            # 提取统计数据
            if "statistics" in item:
                stats = item["statistics"]
                video_info["play_count"] = stats.get("play_count", 0)
                video_info["like_count"] = stats.get("digg_count", 0)
                video_info["comment_count"] = stats.get("comment_count", 0)
            
            return video_info
        except Exception as e:
            print(f"提取TikTok视频信息时出错: {e}")
            return None
    
    def download_video(self, video_url: str, save_dir: str = "data/videos", filename: Optional[str] = None, max_retries: int = 3) -> Optional[str]:
        """
        下载视频文件（带重试机制）
        
        Args:
            video_url (str): 视频URL
            save_dir (str): 保存目录
            filename (str, optional): 文件名，如果不提供则自动生成
            max_retries (int): 最大重试次数
            
        Returns:
            str: 下载文件的路径，失败则返回None
        """
        for attempt in range(max_retries):
            try:
                # 检查URL是否为空
                if not video_url:
                    print("视频URL为空")
                    return None
                
                # 创建保存目录
                os.makedirs(save_dir, exist_ok=True)
                
                # 如果没有提供文件名，则根据URL生成
                if not filename:
                    parsed_url = urlparse(video_url)
                    filename = os.path.basename(parsed_url.path)
                    if not filename or "." not in filename:
                        filename = f"video_{int(time.time())}.mp4"
                
                # 完整文件路径
                file_path = os.path.join(save_dir, filename)
                
                # 检查文件是否已存在
                if os.path.exists(file_path):
                    print(f"文件已存在: {file_path}")
                    return file_path
                
                # 添加请求头模拟浏览器
                headers = {
                    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
                }
                
                # 如果不是第一次尝试，添加范围请求头
                if attempt > 0:
                    print(f"重试下载 (尝试 {attempt + 1}/{max_retries})")
                    headers['Range'] = 'bytes=0-'
                
                # 下载视频
                print(f"正在下载视频: {video_url}")
                response = self.session.get(video_url, stream=True, timeout=1000, headers=headers)
                response.raise_for_status()
                
                # 保存文件
                with open(file_path, 'wb') as f:
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:
                            f.write(chunk)
                
                print(f"视频下载完成: {file_path}")
                return file_path
                
            except Exception as e:
                print(f"下载视频时出错 (尝试 {attempt + 1}/{max_retries}): {e}")
                if attempt < max_retries - 1:
                    time.sleep(2)  # 等待2秒后重试
                else:
                    print("达到最大重试次数，下载失败")
                    return None
    
    def collect_and_process_videos(self, keyword: str, count: int, platform,
                                  target_lang, source_lang) -> Dict:
        """
        收集视频并调用鬼手API进行处理
        
        Args:
            keyword (str): 搜索关键字
            count (int): 收集视频数量
            platform (str): 平台，默认为"douyin"
            target_lang (str): 目标语言，默认为"vi"（越南语）
            source_lang (str): 源语言，默认为"zh"（中文）
            
        Returns:
            Dict: 处理结果
        """
        print(f"开始收集并处理 '{keyword}' 相关的 {count} 个视频")
        
        # 1. 收集视频
        videos = self.collect_videos_by_keyword(keyword, count, platform)
        
        if not videos:
            print("未收集到任何视频，无法继续处理")
            return {"success": False, "message": "未收集到任何视频"}
        
        # 2. 获取鬼手API密钥
        ghostcut_app_key = os.environ.get('GHOSTCUT_APP_KEY')
        ghostcut_app_secret = os.environ.get('GHOSTCUT_APP_SECRET')
        
        if not ghostcut_app_key or not ghostcut_app_secret:
            print("警告: 未设置鬼手API密钥，无法进行视频处理")
            print("请在 .env 文件中添加:")
            print("  GHOSTCUT_APP_KEY=your_ghostcut_app_key")
            print("  GHOSTCUT_APP_SECRET=your_ghostcut_app_secret")
            return {"success": False, "message": "未设置鬼手API密钥"}
        
        # 3. 初始化鬼手翻译器和上传器
        translator = GhostCutVideoTranslator(ghostcut_app_key, ghostcut_app_secret)
        uploader = GhostCutUploader(ghostcut_app_key, ghostcut_app_secret)
        
        # 4. 根据平台决定处理方式
        if platform.lower() == "tiktok":
            # 对于TikTok平台，需要先下载视频再上传到鬼手OSS
            print("TikTok平台: 需要先下载视频再上传到鬼手OSS")
            return self._process_tiktok_videos(videos, keyword, translator, uploader, target_lang, source_lang)
        else:
            # 对于抖音平台，可以直接使用URL处理
            print("抖音平台: 直接使用视频URL进行处理")
            return self._process_douyin_videos(videos, keyword, translator, target_lang, source_lang)
    
    def _process_douyin_videos(self, videos: List[Dict], keyword: str, translator: GhostCutVideoTranslator,
                              target_lang: str, source_lang: str) -> Dict:
        """
        处理抖音平台视频（直接使用URL）
        
        Args:
            videos (List[Dict]): 视频列表
            keyword (str): 关键词
            translator (GhostCutVideoTranslator): 鬼手翻译器
            target_lang (str): 目标语言
            source_lang (str): 源语言
            
        Returns:
            Dict: 处理结果
        """
        # 提取视频URL
        video_urls = [video["video_url"] for video in videos if video.get("video_url")]
        video_names = [f"{keyword}_{i+1}" for i in range(len(video_urls))]
        
        if not video_urls:
            print("没有有效的视频URL，无法进行处理")
            return {"success": False, "message": "没有有效的视频URL"}
        
        print(f"准备处理 {len(video_urls)} 个视频:")
        for i, url in enumerate(video_urls):
            print(f"  {i+1}. {url}")
        
        # 检查数据库中是否已存在相同aweme_id的视频，并且已经处理完成
        # 这是避免重复处理的关键逻辑：检查数据库中是否已存在相同aweme_id且处理状态为"completed"的视频
        filtered_videos = []
        for video in videos:
            aweme_id = video.get("aweme_id")
            if not aweme_id:
                continue
                
            # 查询数据库中是否已存在该视频
            existing_video = self.db.get_video_by_id(aweme_id)
            # 如果视频已存在且处理状态为completed，并且已下载，则跳过处理
            if existing_video and existing_video.processing_status == "completed" and existing_video.processed_download_path:
                print(f"视频 {aweme_id} 已经处理完成并下载，跳过处理")
                continue
                
            filtered_videos.append(video)
        
        if not filtered_videos:
            print("所有视频都已经处理完成，无需再次处理")
            return {"success": True, "message": "所有视频已处理完成", "collected_videos": videos}
        
        # 将视频信息存入数据库
        for video_info in filtered_videos:
            aweme_id = video_info.get("aweme_id", "")
            if not aweme_id:
                continue
                
            # 检查视频是否已存在于数据库中
            if not self.db.video_exists(aweme_id):
                # 添加视频信息到数据库
                db_video = VideoInfo(
                    aweme_id=video_info.get("aweme_id", ""),
                    platform=video_info.get("platform", ""),
                    title=video_info.get("title", ""),
                    description=video_info.get("description", ""),
                    duration=video_info.get("duration", 0),
                    cover_url=video_info.get("cover_url", ""),
                    video_url=video_info.get("video_url", ""),
                    author_name=video_info.get("author_name", ""),
                    author_id=video_info.get("author_id", ""),
                    play_count=video_info.get("play_count", 0),
                    like_count=video_info.get("like_count", 0),
                    comment_count=video_info.get("comment_count", 0),
                    search_keyword=video_info.get("search_keyword", "")
                )
                self.db.add_video(db_video)
            
            # 更新处理状态为初始化
            self.db.update_processing_status(aweme_id, "initialized")
        
        try:
            # 配置参数
            wy_voice_param = {
                "font_param": {
                    "config": {
                        "bgH": 0,
                        "bgPaddingY": 4,
                        "bgR": 0,
                        "bgType": 0,
                        "bgW": 0,
                        "fillStyle": "#FFE200",
                        "fontFamily": "NotoSans",
                        "fontStyleItalic": False,
                        "fontWeightBold": True,
                        "lineSpace": 5,
                        "shadowBlur": 1,
                        "shadowColor": "rgba(0, 0, 0, 1)",
                        "shadowOffsetX": 1,
                        "shadowOffsetY": 1,
                        "strokeLineWidth": 2,
                        "strokeStyle": "#000000",
                        "subtitleAreaWidth": 0.9,
                        "textAlign": "center"
                    },
                    "fontFileName": "NotoSans-Bold.ttf",
                    "font_size": 40,
                    "position": 0.86,
                    "style": "tpl-14-1-T",
                    "subtitleLang": "vi",
                    "videoWidth": 1080
                }
            }
            extra_options = {
                "extra_trim_config": {
                    "modify_md5": False,
                    "extract_frame_on": False,
                    "adjust_color_on": False,
                    "adjust_sharpness_on": False,
                    "crop_trailer_on": False,
                    "speedup_on": False
                },
                "extra_video_translate_config": {
                    "simplification_on": True
                }
            }
            
            # 过滤后的视频URL和名称
            filtered_video_data = [(video["video_url"], video["title"], video["aweme_id"]) 
                                  for video in filtered_videos if video.get("video_url") and video.get("title") and video.get("aweme_id")]
            
            # 分批处理视频，每批最多20个视频
            batch_size = 20
            all_results = []
            success_count = 0
            
            for i in range(0, len(filtered_video_data), batch_size):
                batch = filtered_video_data[i:i+batch_size]
                batch_urls = [item[0] for item in batch]
                batch_names = [item[1] for item in batch]
                
                print(f"正在处理第 {i//batch_size + 1} 批视频，共 {len(batch)} 个")
                
                result = translator.translate_videos(
                    urls=batch_urls,
                    source_lang=source_lang,
                    target_lang=target_lang,
                    names=batch_names,
                    resolution="1080p",
                    wy_voice_param=wy_voice_param,
                    remove_bg_audio=0,  # 背景音保持原样
                    extra_options=extra_options,
                )
                
                all_results.append(result)
                
                # 更新数据库中的处理状态为pending
                if result.get("code") == 1000 and "body" in result and "dataList" in result["body"]:
                    data_list = result["body"]["dataList"]
                    for item in data_list:
                        # 找到对应的视频ID
                        video_url = item.get("url")
                        for video_url_item, video_title, aweme_id in batch:
                            if video_url_item == video_url:
                                task_id = item.get("id")
                                if aweme_id and task_id:
                                    self.db.update_processing_status(aweme_id, "pending", str(task_id), video_url)
                                    print(f"视频 {aweme_id} 已提交处理，任务ID: {task_id}")
                                    success_count += 1
                                break
                else:
                    print(f"调用鬼手API失败: {result.get('msg', '未知错误')}")
                
                # 添加延迟避免请求过于频繁
                if i + batch_size < len(filtered_video_data):
                    time.sleep(1)
            
            print(f"成功提交 {success_count} 个视频进行处理")
            
            return {
                "success": True,
                "collected_videos": videos,
                "filtered_videos": filtered_videos,
                "processing_results": all_results
            }
            
        except Exception as e:
            print(f"调用鬼手API处理视频时出错: {e}")
            import traceback
            traceback.print_exc()
            return {
                "success": False,
                "message": f"调用鬼手API处理视频时出错: {e}",
                "collected_videos": videos
            }

    def _process_tiktok_videos(self, videos: List[Dict], keyword: str, translator: GhostCutVideoTranslator,
                              uploader: GhostCutUploader, target_lang: str, source_lang: str) -> Dict:
        """
        处理TikTok平台视频（需要先下载再上传到OSS）
        
        Args:
            videos (List[Dict]): 视频列表
            keyword (str): 关键词
            translator (GhostCutVideoTranslator): 鬼手翻译器
            uploader (GhostCutUploader): 鬼手上传器
            target_lang (str): 目标语言
            source_lang (str): 源语言
            
        Returns:
            Dict: 处理结果
        """
        # 检查数据库中是否已存在相同aweme_id的视频，并且已经处理完成
        filtered_videos = []
        for video in videos:
            aweme_id = video.get("aweme_id")
            if not aweme_id:
                continue
                
            # 查询数据库中是否已存在该视频
            existing_video = self.db.get_video_by_id(aweme_id)
            # 如果视频已存在且处理状态为completed，并且已下载，则跳过处理
            if existing_video and existing_video.processing_status == "completed" and existing_video.processed_download_path:
                print(f"视频 {aweme_id} 已经处理完成并下载，跳过处理")
                continue
                
            filtered_videos.append(video)
        
        if not filtered_videos:
            print("所有视频都已经处理完成，无需再次处理")
            return {"success": True, "message": "所有视频已处理完成", "collected_videos": videos}
        
        # 下载并上传视频
        uploaded_videos = []
        for i, video in enumerate(filtered_videos):
            aweme_id = video.get("aweme_id")
            video_url = video.get("video_url")
            title = video.get("title", f"video_{i+1}")
            
            if not aweme_id or not video_url:
                print(f"视频 {aweme_id or 'unknown'} 信息不完整，跳过处理")
                continue
            
            try:
                print(f"正在处理视频 {i+1}/{len(filtered_videos)}: {title}")
                
                # 1. 下载视频到本地
                print(f"  正在下载视频: {video_url}")
                download_path = self.download_video(video_url, save_dir=f"data/tiktok_videos/{keyword}", 
                                                  filename=f"{aweme_id}.mp4")
                
                if not download_path or not os.path.exists(download_path):
                    print(f"  视频下载失败: {video_url}")
                    continue
                
                print(f"  视频下载成功: {download_path}")
                
                # 2. 上传视频到鬼手OSS
                print(f"  正在上传视频到鬼手OSS...")
                # 生成随机nonce
                import time
                nonce = f"tiktok_{aweme_id}_{int(time.time())}"
                
                # 获取上传凭证
                policy = uploader.get_upload_policy(nonce, "video")
                
                # 上传文件
                uploaded_url = uploader.upload_file(policy, download_path, f"{aweme_id}.mp4")
                print(f"  视频上传成功: {uploaded_url}")
                
                # 3. 保存视频信息到数据库
                if not self.db.video_exists(aweme_id):
                    # 添加视频信息到数据库
                    db_video = VideoInfo(
                        aweme_id=aweme_id,
                        platform=video.get("platform", "tiktok"),
                        title=title,
                        description=video.get("description", ""),
                        duration=video.get("duration", 0),
                        cover_url=video.get("cover_url", ""),
                        video_url=video_url,
                        author_name=video.get("author_name", ""),
                        author_id=video.get("author_id", ""),
                        play_count=video.get("play_count", 0),
                        like_count=video.get("like_count", 0),
                        comment_count=video.get("comment_count", 0),
                        search_keyword=keyword,
                        download_path=download_path  # 保存本地下载路径
                    )
                    self.db.add_video(db_video)
                
                # 更新处理状态为初始化
                self.db.update_processing_status(aweme_id, "initialized")
                
                # 保存上传信息
                uploaded_videos.append({
                    "aweme_id": aweme_id,
                    "local_path": download_path,
                    "oss_url": uploaded_url,
                    "title": title
                })
                
                # 清理本地下载的文件（可选）
                # os.remove(download_path)
                
            except Exception as e:
                print(f"  处理视频 {aweme_id} 时出错: {e}")
                import traceback
                traceback.print_exc()
                continue
        
        if not uploaded_videos:
            print("没有成功上传任何视频到OSS")
            return {"success": False, "message": "没有成功上传任何视频到OSS"}
        
        print(f"成功上传 {len(uploaded_videos)} 个视频到OSS")
        
        # 使用上传的OSS URL调用鬼手翻译API
        try:
            # 配置参数
            wy_voice_param = {
                "font_param": {
                    "config": {
                        "bgH": 0,
                        "bgPaddingY": 4,
                        "bgR": 0,
                        "bgType": 0,
                        "bgW": 0,
                        "fillStyle": "#FFE200",
                        "fontFamily": "NotoSans",
                        "fontStyleItalic": False,
                        "fontWeightBold": True,
                        "lineSpace": 5,
                        "shadowBlur": 1,
                        "shadowColor": "rgba(0, 0, 0, 1)",
                        "shadowOffsetX": 1,
                        "shadowOffsetY": 1,
                        "strokeLineWidth": 2,
                        "strokeStyle": "#000000",
                        "subtitleAreaWidth": 0.9,
                        "textAlign": "center"
                    },
                    "fontFileName": "NotoSans-Bold.ttf",
                    "font_size": 40,
                    "position": 0.86,
                    "style": "tpl-14-1-T",
                    "subtitleLang": "vi",
                    "videoWidth": 1080
                }
            }
            extra_options = {
                "extra_trim_config": {
                    "modify_md5": False,
                    "extract_frame_on": False,
                    "adjust_color_on": False,
                    "adjust_sharpness_on": False,
                    "crop_trailer_on": False,
                    "speedup_on": False
                },
                "extra_video_translate_config": {
                    "simplification_on": True
                }
            }
            
            # 准备上传的视频URL和名称
            video_urls = [video["oss_url"] for video in uploaded_videos]
            video_names = [video["title"] for video in uploaded_videos]
            aweme_ids = [video["aweme_id"] for video in uploaded_videos]
            
            print(f"准备处理 {len(video_urls)} 个已上传的视频:")
            for i, (url, name) in enumerate(zip(video_urls, video_names)):
                print(f"  {i+1}. {name}: {url}")
            
            # 分批处理视频，每批最多20个视频
            batch_size = 20
            all_results = []
            success_count = 0
            
            for i in range(0, len(video_urls), batch_size):
                batch_urls = video_urls[i:i+batch_size]
                batch_names = video_names[i:i+batch_size]
                batch_aweme_ids = aweme_ids[i:i+batch_size]
                
                print(f"正在处理第 {i//batch_size + 1} 批视频，共 {len(batch_urls)} 个")
                
                result = translator.translate_videos(
                    urls=batch_urls,
                    source_lang=source_lang,
                    target_lang=target_lang,
                    names=batch_names,
                    resolution="1080p",
                    wy_voice_param=wy_voice_param,
                    remove_bg_audio=0,  # 背景音保持原样
                    extra_options=extra_options,
                )
                
                all_results.append(result)
                
                # 更新数据库中的处理状态为pending
                if result.get("code") == 1000 and "body" in result and "dataList" in result["body"]:
                    data_list = result["body"]["dataList"]
                    for item in data_list:
                        # 找到对应的视频ID
                        video_url = item.get("url")
                        for j, (batch_url, batch_name, batch_aweme_id) in enumerate(zip(batch_urls, batch_names, batch_aweme_ids)):
                            if batch_url == video_url:
                                task_id = item.get("id")
                                if batch_aweme_id and task_id:
                                    self.db.update_processing_status(batch_aweme_id, "pending", str(task_id), video_url)
                                    print(f"视频 {batch_aweme_id} 已提交处理，任务ID: {task_id}")
                                    success_count += 1
                                break
                else:
                    print(f"调用鬼手API失败: {result.get('msg', '未知错误')}")
                
                # 添加延迟避免请求过于频繁
                if i + batch_size < len(video_urls):
                    time.sleep(1)
            
            print(f"成功提交 {success_count} 个视频进行处理")
            
            return {
                "success": True,
                "collected_videos": videos,
                "filtered_videos": filtered_videos,
                "uploaded_videos": uploaded_videos,
                "processing_results": all_results
            }
            
        except Exception as e:
            print(f"调用鬼手API处理视频时出错: {e}")
            import traceback
            traceback.print_exc()
            return {
                "success": False,
                "message": f"调用鬼手API处理视频时出错: {e}",
                "collected_videos": videos
            }
    
    def get_downloaded_videos(self) -> List[VideoInfo]:
        """
        获取所有已下载的视频
        
        Returns:
            List[VideoInfo]: 已下载的视频列表
        """
        return self.db.get_all_downloaded_videos()
    
    def get_videos_by_keyword(self, keyword: str) -> List[VideoInfo]:
        """
        根据关键词获取已下载的视频
        
        Args:
            keyword (str): 搜索关键词
            
        Returns:
            List[VideoInfo]: 相关视频列表
        """
        return self.db.get_videos_by_keyword(keyword)

    def fetch_one_video_by_share_url(self, share_url: str) -> Optional[Dict]:
        """
        通过分享链接获取单个视频信息
        
        Args:
            share_url (str): 视频分享链接
            
        Returns:
            Dict: 视频信息
        """
        try:
            # 获取平台端点配置
            endpoint_config = get_endpoint_config(self.platform, "fetch_one_video_by_share_url")
            if not endpoint_config:
                # 根据平台设置默认端点
                if self.platform == "tiktok":
                    endpoint_config = EndpointConfig(
                        path="/api/v1/tiktok/app/v3/fetch_one_video_by_share_url",
                        method="GET",
                        param_type="query"
                    )
                else:
                    endpoint_config = EndpointConfig(
                        path="/api/v1/douyin/app/v3/fetch_one_video_by_share_url",
                        method="GET",
                        param_type="query"
                    )
            
            # 构建完整URL
            config = get_platform_config(self.platform)
            base_url = config.base_url if config else self.base_url
            url = f"{base_url}{endpoint_config.path}"
            
            params = {"share_url": share_url}
            print(f"请求URL: {url}")
            
            # 根据端点配置决定HTTP方法
            if endpoint_config.method.upper() == "POST":
                response = self.session.post(url, params=params if endpoint_config.param_type == "query" else None,
                                           json=params if endpoint_config.param_type == "json" else None)
            else:
                response = self.session.get(url, params=params)
            
            response.raise_for_status()
            
            return response.json()
        except Exception as e:
            print(f"通过分享链接获取视频信息时出错: {e}")
            return None

    def fetch_user_post_videos(self, sec_user_id: str, count: int = 20) -> List[Dict]:
        """
        获取用户发布的视频列表
        
        Args:
            sec_user_id (str): 用户ID
            count (int): 获取视频数量
            
        Returns:
            List[Dict]: 视频列表
        """
        try:
            # 获取平台端点配置
            endpoint_config = get_endpoint_config(self.platform, "fetch_user_post_videos")
            if not endpoint_config:
                # 根据平台设置默认端点
                if self.platform == "tiktok":
                    endpoint_config = EndpointConfig(
                        path="/api/v1/tiktok/app/v3/fetch_user_post_videos",
                        method="GET",
                        param_type="query"
                    )
                else:
                    endpoint_config = EndpointConfig(
                        path="/api/v1/douyin/app/v3/fetch_user_post_videos",
                        method="GET",
                        param_type="query"
                    )
            
            # 构建完整URL
            config = get_platform_config(self.platform)
            base_url = config.base_url if config else self.base_url
            url = f"{base_url}{endpoint_config.path}"
            
            params = {
                "sec_user_id": sec_user_id,
                "count": count
            }
            print(f"请求URL: {url}")
            
            # 根据端点配置决定HTTP方法
            if endpoint_config.method.upper() == "POST":
                response = self.session.post(url, params=params if endpoint_config.param_type == "query" else None,
                                           json=params if endpoint_config.param_type == "json" else None)
            else:
                response = self.session.get(url, params=params)
            
            response.raise_for_status()
            
            data = response.json()
            videos = []
            
            # 解析用户视频数据
            if isinstance(data, dict) and "data" in data:
                if "videos" in data["data"] and isinstance(data["data"]["videos"], list):
                    videos = data["data"]["videos"]
                elif isinstance(data["data"], list):
                    videos = data["data"]
            
            return videos
        except Exception as e:
            print(f"获取用户视频列表时出错: {e}")
            return []

    def check_processing_status(self):
        """
        检查数据库中所有处理状态为pending的视频，并轮询鬼手API获取处理结果
        同时处理状态为initialized的视频，将其重新提交处理
        对于失败的任务，尝试重试最多3次
        """
        print("开始检查处理中的视频状态...")
        
        # 获取所有处理状态为pending的视频
        self.db.mark_expired_videos_as_timeout()
        pending_videos = self.db.get_pending_videos()
        if not pending_videos:
            print("没有处理中的视频")
        else:
            print(f"找到 {len(pending_videos)} 个处理中的视频")
            
            # 获取鬼手API密钥
            ghostcut_app_key = os.environ.get('GHOSTCUT_APP_KEY')
            ghostcut_app_secret = os.environ.get('GHOSTCUT_APP_SECRET')
            
            if not ghostcut_app_key or not ghostcut_app_secret:
                print("警告: 未设置鬼手API密钥，无法检查视频处理状态")
                return
            
            # 初始化鬼手翻译器
            translator = GhostCutVideoTranslator(ghostcut_app_key, ghostcut_app_secret)
            
            # 检查每个视频的处理状态
            for video in pending_videos:
                try:
                    task_id = video.ghostcut_task_id
                    if not task_id:
                        continue
                    
                    # 确保task_id是数字
                    try:
                        task_id_int = int(task_id)
                    except ValueError:
                        print(f"无效的任务ID: {task_id}，跳过视频 {video.aweme_id}")
                        continue
                    
                    print(f"检查视频 {video.aweme_id} 的处理状态 (任务ID: {task_id})")
                    
                    # 调用鬼手API查询任务状态
                    status_result = translator.query_task_status_by_work_ids(task_id_int)
                    # 解析并显示每个任务的详细状态
                    if status_result.get("body", {}).get("content"):
                        print("\n详细任务状态:")
                        for task in status_result["body"]["content"]:
                            task_id = task.get("id")
                            process_status = task.get("processStatus")
                            process_progress = task.get("processProgress", 0)
                            
                            # 根据processStatus值判断状态
                            status_text = "未知"
                            if process_status == 0:
                                status_text = "等待处理"
                            elif process_status == 1:
                                status_text = "处理完成"
                                # 处理完成，更新状态并下载视频
                                processed_url = task["videoUrl"]
                                if processed_url:
                                    self.db.update_processing_status(
                                        video.aweme_id, 
                                        "completed", 
                                        task_id, 
                                        processed_url
                                    )
                                    print(f"视频 {video.aweme_id} 处理完成，准备下载...")
                                    self._download_processed_video(video, processed_url)
                                else:
                                    self.db.update_processing_status(video.aweme_id, "no_video_url", task_id)
                                    print(f"视频 {video.aweme_id} 处理完成但无下载链接")

                            elif process_status > 1:
                                status_text = "处理失败"
                                # 处理失败，尝试重试
                                if video.retry_count < 3:
                                    print(f"视频 {video.aweme_id} 处理失败，尝试重试 (第{video.retry_count + 1}次)")
                                    retry_result = translator.retry_task(task_id_int)
                                    if retry_result.get("code") == 1000:
                                        # 重试成功，更新重试次数
                                        self.db.update_processing_status(
                                            video.aweme_id, 
                                            "pending", 
                                            task_id, 
                                            None,  # processed_url
                                            video.retry_count + 1
                                        )
                                        print(f"视频 {video.aweme_id} 重试成功，任务ID: {task_id}")
                                    else:
                                        # 重试失败
                                        self.db.update_processing_status(
                                            video.aweme_id, 
                                            "failed", 
                                            task_id, 
                                            None,  # processed_url
                                            video.retry_count + 1
                                        )
                                        print(f"视频 {video.aweme_id} 重试失败: {retry_result.get('msg', '未知错误')}")
                                else:
                                    # 已达到最大重试次数，标记为失败
                                    self.db.update_processing_status(video.aweme_id, "failed", task_id)
                                    print(f"视频 {video.aweme_id} 处理失败且已达到最大重试次数")

                            print(f"  任务ID: {task_id}")
                            print(f"    处理状态: {process_status} ({status_text})")
                            print(f"    处理进度: {process_progress}%")
                            print()
                        
                except Exception as e:
                    print(f"检查视频 {video.aweme_id} 处理状态时出错: {e}")
                    import traceback
                    traceback.print_exc()
        
        # 处理处于initialized状态的视频
        initialized_videos = self._get_initialized_videos()
        if initialized_videos:
            print(f"发现 {len(initialized_videos)} 个处于initialized状态的视频，尝试重新处理...")
            self._process_initialized_videos(initialized_videos)
        else:
            print("没有需要重新处理的initialized状态视频")

    def _get_initialized_videos(self):
        """
        获取所有处理状态为initialized的视频
        
        Returns:
            List[VideoInfo]: initialized状态的视频列表
        """
        try:
            with sqlite3.connect(self.db.db_path) as conn:
                cursor = conn.cursor()
                cursor.execute("SELECT * FROM videos WHERE processing_status = 'initialized'")
                rows = cursor.fetchall()
                return [VideoInfo(
                    aweme_id=row[1], platform=row[2], title=row[3],
                    description=row[4], duration=row[5], cover_url=row[6],
                    video_url=row[7], author_name=row[8], author_id=row[9],
                    play_count=row[10], like_count=row[11], comment_count=row[12],
                    download_path=row[13], download_time=row[14], search_keyword=row[15],
                    create_time=row[16], processing_status=row[17], ghostcut_task_id=row[18],
                    processed_video_url=row[19], processed_download_path=row[20],
                    last_check_time=row[21], retry_count=row[22] or 0
                ) for row in rows]
        except Exception as e:
            print(f"查询initialized视频时出错: {e}")
            return []

    def _process_initialized_videos(self, initialized_videos):
        """
        处理处于initialized状态的视频
        
        Args:
            initialized_videos (List[VideoInfo]): initialized状态的视频列表
        """
        # 获取鬼手API密钥
        ghostcut_app_key = os.environ.get('GHOSTCUT_APP_KEY')
        ghostcut_app_secret = os.environ.get('GHOSTCUT_APP_SECRET')
        
        if not ghostcut_app_key or not ghostcut_app_secret:
            print("警告: 未设置鬼手API密钥，无法处理initialized状态的视频")
            return
        
        # 初始化鬼手翻译器
        translator = GhostCutVideoTranslator(ghostcut_app_key, ghostcut_app_secret)
        
        # 准备视频URL和名称列表
        video_data = [(video.video_url, video.title, video.aweme_id) for video in initialized_videos if video.video_url]
        
        if not video_data:
            print("没有有效的视频URL，无法进行处理")
            return
        
        try:
            # 配置参数
            wy_voice_param = {
                "font_param": {
                    "config": {
                        "bgH": 0,
                        "bgPaddingY": 4,
                        "bgR": 0,
                        "bgType": 0,
                        "bgW": 0,
                        "fillStyle": "#FFE200",
                        "fontFamily": "NotoSans",
                        "fontStyleItalic": False,
                        "fontWeightBold": True,
                        "lineSpace": 5,
                        "shadowBlur": 1,
                        "shadowColor": "rgba(0, 0, 0, 1)",
                        "shadowOffsetX": 1,
                        "shadowOffsetY": 1,
                        "strokeLineWidth": 2,
                        "strokeStyle": "#000000",
                        "subtitleAreaWidth": 0.9,
                        "textAlign": "center"
                    },
                    "fontFileName": "NotoSans-Bold.ttf",
                    "font_size": 40,
                    "position": 0.86,
                    "style": "tpl-14-1-T",
                    "subtitleLang": "vi",
                    "videoWidth": 1080
                }
            }
            
            extra_options = {
                "extra_trim_config": {
                    "modify_md5": False,
                    "extract_frame_on": False,
                    "adjust_color_on": False,
                    "adjust_sharpness_on": False,
                    "crop_trailer_on": False,
                    "speedup_on": False
                },
                "extra_video_translate_config": {
                    "simplification_on": True
                }
            }
            
            # 分批处理视频，每批最多20个
            batch_size = 20
            for i in range(0, len(video_data), batch_size):
                batch = video_data[i:i+batch_size]
                batch_urls = [item[0] for item in batch]
                batch_names = [item[1] for item in batch]
                
                print(f"正在处理第 {i//batch_size + 1} 批视频，共 {len(batch)} 个")
                
                # 调用鬼手API进行视频翻译处理
                result = translator.translate_videos(
                    urls=batch_urls,
                    source_lang="zh",
                    target_lang="vi",
                    names=batch_names,
                    resolution="1080p",
                    wy_voice_param=wy_voice_param,
                    remove_bg_audio=0,  # 背景音保持原样
                    extra_options=extra_options,
                )
                
                print("鬼手API处理结果:")
                print(json.dumps(result, indent=2, ensure_ascii=False))
                
                # 更新数据库中的处理状态为pending
                if result.get("code") == 1000 and "body" in result and "dataList" in result["body"]:
                    data_list = result["body"]["dataList"]
                    for item in data_list:
                        # 找到对应的视频ID
                        video_url = item.get("url")
                        for video_url_item, video_title, aweme_id in batch:
                            if video_url_item == video_url:
                                task_id = item.get("id")
                                if aweme_id and task_id:
                                    # 对于重新处理的视频，重置重试次数为0
                                    self.db.update_processing_status(aweme_id, "pending", str(task_id), video_url, 0)
                                    print(f"视频 {aweme_id} 已重新提交处理，任务ID: {task_id}")
                                break
                else:
                    print(f"调用鬼手API失败: {result.get('msg', '未知错误')}")
                
                # 添加延迟避免请求过于频繁
                if i + batch_size < len(video_data):
                    time.sleep(1)
                
        except Exception as e:
            print(f"调用鬼手API处理视频时出错: {e}")
            import traceback
            traceback.print_exc()
    def _download_processed_video(self, video: VideoInfo, processed_url: str):
        """
        下载处理完成的视频
        
        Args:
            video (VideoInfo): 视频信息
            processed_url (str): 处理后的视频URL
        """
        try:
            print(f"开始下载处理后的视频: {processed_url}")
            
            # 获取基础调度目录
            base_schedule_dir = os.environ.get('BASE_SCHEDULE_DIR', 'data/scheduled_videos')
            
            # 创建日期目录 (YYYYMMDD)
            today = datetime.now().strftime("%Y%m%d")
            date_dir = os.path.join(base_schedule_dir, today)
            
            # 创建搬运目录
            move_dir = os.path.join(date_dir, "搬运")
            
            # 创建关键词子目录
            keyword_dir = os.path.join(move_dir, video.search_keyword or "unknown")
            
            # 创建完整目录结构
            os.makedirs(keyword_dir, exist_ok=True)
            
            # 获取视频对应的关键词配置，以确定源语言和目标语言
            keyword_config = self.db.get_keyword_config_by_keyword(video.search_keyword or "")
            source_lang = keyword_config.source_lang
            target_lang = keyword_config.target_lang
            
            # 使用AI生成目标语言的文件名
            translated_filename = self._generate_target_language_filename(video.title, source_lang, target_lang)
            filename = f"{translated_filename}.mp4"
            file_path = os.path.join(keyword_dir, filename)
            
            # 如果文件已存在，添加序号
            counter = 1
            original_file_path = file_path
            while os.path.exists(file_path):
                name, ext = os.path.splitext(original_file_path)
                file_path = f"{name}_{counter}{ext}"
                counter += 1
            
            # 下载视频
            response = self.session.get(processed_url, stream=True)
            response.raise_for_status()
            
            with open(file_path, 'wb') as f:
                for chunk in response.iter_content(chunk_size=8192):
                    if chunk:
                        f.write(chunk)

            if '足球' in video.search_keyword:
                embed_football_ad_single(file_path)
            else:
                embed_game_ad_single(file_path)

            transcoded_output_path = file_path.replace('.mp4', '_transcoded.mp4')
            print(f"正在转码视频以达到录制效果: {transcoded_output_path}")
            transcode_success = transcode_video_for_recording(file_path, transcoded_output_path)
            
            if transcode_success:
                # 转码成功，删除原始文件，保留转码后的文件
                os.remove(file_path)
                # 重命名转码后的文件为原始文件名
                os.rename(transcoded_output_path, file_path)
                print(f"视频转码完成并已替换原始文件: {file_path}")
            else:
                print("视频转码失败，保留原始视频文件")
            print(f"处理后的视频下载完成: {file_path}")
            
            # 更新数据库中的下载路径
            self.db.update_processed_download_info(video.aweme_id, file_path)
            
        except Exception as e:
            print(f"下载处理后的视频时出错: {e}")
            # 更新状态为失败
            self.db.update_processing_status(video.aweme_id, "failed", video.ghostcut_task_id)
    
    def _generate_target_language_filename(self, original_title: str, source_lang: str, target_lang: str) -> str:
        """
        使用AI生成目标语言的文件名
        
        Args:
            original_title (str): 原始文件名/视频标题
            source_lang (str): 源语言代码
            target_lang (str): 目标语言代码
            
        Returns:
            str: 翻译后的文件名
        """
        try:
            # 获取API密钥
            api_key = os.getenv('DASHSCOPE_API_KEY')
            if not api_key:
                print("警告: 未设置DASHSCOPE_API_KEY环境变量，将使用原始文件名")
                return original_title
            
            # 设置API密钥
            dashscope.api_key = api_key
            
            # 语言代码映射到语言名称
            lang_names = {
                "zh": "中文",
                "vi": "越南语",
                "en": "英语",
                "th": "泰语",
                "id": "印尼语",
                "ja": "日语",
                "ko": "韩语",
                "ru": "俄语",
                "es": "西班牙语",
                "fr": "法语",
                "de": "德语",
                "pt": "葡萄牙语",
                "tr": "土耳其语",
                "ar": "阿拉伯语",
                "pt-br": "巴西葡萄牙语"
            }
            
            source_lang_name = lang_names.get(source_lang, source_lang)
            target_lang_name = lang_names.get(target_lang, target_lang)
            
            # 构建消息
            messages = [
                {
                    "role": "system",
                    "content": f"你是一个视频搬运工，请将用户提供的{source_lang_name}内容二创成{target_lang_name}语音的标题。"
                               f"翻译结果要朗朗上口，吸引人的眼球，还要与原来的内容有相关性。"
                },
                {
                    "role": "user",
                    "content": original_title
                }
            ]
            
            # 调用通义千问API进行翻译
            response = Generation.call(
                model="qwen-turbo",
                messages=messages,
                result_format='message'
            )
            
            if response.status_code == 200 and response.output and response.output.choices:
                translated_title = response.output.choices[0].message.content
                # 清理文件名中的非法字符
                illegal_chars = ['<', '>', ':', '"', '/', '\\', '|', '?', '*']
                for char in illegal_chars:
                    translated_title = translated_title.replace(char, '')
                # 去除首尾空格
                translated_title = translated_title.strip()
                # 如果翻译结果为空，返回原始标题
                if not translated_title:
                    return original_title
                return translated_title
            else:
                print(f"翻译API调用失败，状态码: {response.status_code}")
                return original_title
                
        except Exception as e:
            print(f"生成目标语言文件名时出错: {e}")
            return original_title
